
package com.huaweicloud.reqmt.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 节假日检查 Util
 * DateFormats对于多线程使用本质上是不安全的. 更多: JDK Bug #6231579 和 JDK Bug #6178997
 * 
 * @since 2022-11-10
 */
public class HoildayCheckUtil {
    // 节假日List
    private static List<String> hoildayList =
        Arrays.asList("20220101", "20220102", "20220103", "20220108", "20220109", "20220115", "20220116", "20220122",
            "20220123", "20220129", "20220130", "20220131", "20220201", "20220202", "20220203", "20220204", "20220205",
            "20220206", "20220212", "20220213", "20220219", "20220220", "20220227", "20220305", "20220306", "20220312",
            "20220313", "20220319", "20220320", "20220327", "20220403", "20220404", "20220405", "20220409", "20220410",
            "20220416", "20220417", "20220423", "20220501", "20220502", "20220503", "20220504", "20220508", "20220514",
            "20220515", "20220521", "20220522", "20220529", "20220603", "20220604", "20220605", "20220611", "20220612",
            "20220618", "20220619", "20220626", "20220702", "20220703", "20220709", "20220710", "20220716", "20220717",
            "20220723", "20220724", "20220731", "20220806", "20220807", "20220813", "20220814", "20220820", "20220821",
            "20220828", "20220903", "20220904", "20220910", "20220911", "20220912", "20220917", "20220918", "20220925",
            "20221001", "20221002", "20221003", "20221004", "20221005", "20221006", "20221007", "20221015", "20221016",
            "20221022", "20221023", "20221030", "20221105", "20221106", "20221112", "20221113", "20221119", "20221120",
            "20221127", "20221203", "20221204", "20221210", "20221211", "20221217", "20221218", "20221224", "20221225");

    /**
     * 判断并剔除时间List中有多少的节假日
     * 
     * @param timeList 传入的时间List
     * @return 返回剔除节假日的List
     */
    public static synchronized List sortOutHoilday(List timeList) {
        // 存在即移除
        for (String element : hoildayList) {
            timeList.remove(element);
        }
        return timeList;
    }

    /**
     * 计算去除节假日的时长
     *
     * @param date String类型的时间
     * @param isNextDay 计算的是从传入时间到当日凌晨还是到次日凌晨, 次日凌晨: true, 当日凌晨: false
     * @return 时间间隔(秒)
     * @throws ParseException 时间转换异常
     */
    public static synchronized Long judgeDateDuration(String date, boolean isNextDay) throws ParseException {
        SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 判断是否是节假日, 是的话直接返回0
        if (hoildayList.contains(dateFormat(date))) {
            return 0L;
        } else {
            Calendar cd = Calendar.getInstance();
            // 判断计算的是开始时间还是结束时间
            if (isNextDay) {
                // 当前计算的是start_time, 判断距离当天的23:29:29有多少秒
                cd.setTime(inputSdf.parse(date));
                long startTimestamp = cd.getTimeInMillis() / 1000;
                String endDate = date.substring(0, 10) + " 23:59:59";
                cd.setTime(inputSdf.parse(endDate));
                long endTimestamp = cd.getTimeInMillis() / 1000;
                return endTimestamp - startTimestamp;
            } else {
                // 当前计算的是end_time, 判断距离当天的00:00:00有多少秒
                cd.setTime(inputSdf.parse(date));
                long startTimestamp = cd.getTimeInMillis() / 1000;
                String endDate = date.substring(0, 10) + " 00:00:00";
                cd.setTime(inputSdf.parse(endDate));
                long endTimestamp = cd.getTimeInMillis() / 1000;
                return startTimestamp - endTimestamp;
            }
        }
    }

    /**
     * 把从开始时间到结束时间的每天的yyyyMMdd日期放置到指定List中
     *
     * @param startTime 方案的开始时间
     * @param endTime 方案的结束时间
     * @return 返回一个包含了时间间隔的List
     * @throws ParseException 时间转换异常, 输入格式不符合指定格式时会发生
     */
    public static synchronized List getTimeList(String startTime, String endTime) throws ParseException {
        SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 初始化日历
        Calendar cd = Calendar.getInstance();
        List<String> timeList = new ArrayList<>();
        cd.setTime(inputSdf.parse(startTime));
        cd.add(Calendar.DATE, 1);
        Date startDate = cd.getTime();
        String tmpEndTime = dateFormat(endTime);
        // 当前时间
        Date thisDate = startDate;
        String thisTime = dateFormat(thisDate);
        // 添加
        while (Integer.parseInt(thisTime) < Integer.parseInt(tmpEndTime)) {
            // 设置时间
            cd.setTime(thisDate);
            // 该时间增加一天
            cd.add(Calendar.DATE, 1);
            timeList.add(thisTime);
            thisDate = cd.getTime();
            thisTime = dateFormat(thisDate);
        }
        return timeList;
    }

    /**
     * 将传入的String类型的date转换为yyyyMMdd格式的String date
     *
     * @param date yyyy-MM-dd HH:mm:ss 的时间
     * @return 返回
     * @throws ParseException 时间转换异常
     */
    public static String dateFormat(String date) throws ParseException {
        SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat outputSdf = new SimpleDateFormat("yyyyMMdd");
        Date startDate = inputSdf.parse(date);
        return outputSdf.format(startDate);
    }

    /**
     * 将传入的Date转换为yyyyMMdd格式的日期
     *
     * @param date Date类型的日期
     * @return 返回yyyyMMdd格式的日期
     */
    public static String dateFormat(Date date) {
        SimpleDateFormat outputSdf = new SimpleDateFormat("yyyyMMdd");
        return outputSdf.format(date);
    }
}
